package com.jiaai.cloud.base.util;



import com.google.common.collect.HashMultiset;
import com.google.common.collect.Multiset;
import com.jiaai.cloud.base.exception.ServiceException;
import com.jiaai.cloud.base.redis.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


import java.util.Calendar;
import java.util.Map;

/**
 * <p>
 * id 生成器配制文件
 * 结合Redis绶存实现全局Id生成器
 *
 * </p>
 *
 * @author 佳爱网络科技
 * @version V1.0
 * @title IdWorkUtil
 * @since 2017/8/2
 */
public class IdWorkUtil {
    private static  final Logger log= LoggerFactory.getLogger(IdWorkUtil.class);
    private static Multiset<String> currentIds= HashMultiset.create();
    private RedisUtil redisUtil;
    private  Integer machineId;
    private  String cacheKey;
    /**
     *
     * @param redisUtil redis 工具类
     * @param machineId 机器识别码
     */
    public  IdWorkUtil(RedisUtil redisUtil,Integer machineId){
        this.redisUtil=redisUtil;
        this.machineId=machineId;
        this.cacheKey="idWork_"+machineId;
        initData();
    }

    /**
     * 机器码+年份前二位+月分(不足二位后一位补0)+日(不足二位后一位补0)+流水编号（不足长度时前面补0)
     * @param postfix 标识
     * @param length 生成的长度
     * @return
     * @throws ServiceException
     */
    public String  generateId(String postfix ,int length)throws ServiceException {
        int maxId=0;
        try{
             maxId=currentIds.count(postfix);
            if(maxId==0){
                maxId=1;
                currentIds.add(postfix,maxId);
            }else {
                maxId++;
                currentIds.setCount(postfix,maxId);
            }
            Calendar a=Calendar.getInstance();
            String y=String.valueOf(a.get(Calendar.YEAR)).substring(0,1);
            String m= StringUtils.rightPad(String.valueOf(a.get(Calendar.MONTH)+1),2,"0");
            String d=StringUtils.rightPad(String.valueOf(a.get(Calendar.DATE)),2,"0");
            String id=machineId+y+m+d+StringUtils.leftPad(String.valueOf(maxId),length,"0");
            return id;

        }catch (Exception e){
            throw new ServiceException("生成Id失败,"+e.getMessage());
        }finally {
            try{
                    redisUtil.hashSet(0,cacheKey,postfix,String.valueOf(maxId));
                }catch (Exception e){
                    log.error("更新["+postfix+"]id异常,当前最大值"+maxId);

            }
       }


    }
    /**
     * 初始化绶存
     */
    private void initData(){
         Map<String,String> data=redisUtil.hashGetAll(0,cacheKey);
         if(data!=null && data.size()>0){
             for (Map.Entry<String,String> entry:data.entrySet()) {
                 String key=entry.getKey();
                 Integer id= Integer.valueOf(entry.getValue());
                 currentIds.add(key,id);
             }
         }

    }

}
